﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using PloobsEngine.Utils.RoundLine;


namespace PloobsEngine.Features
{
    public enum Quadrant
    {
        LEFT_UP = 0,LEFT_DOWN,RIGHT_UP,RIGHT_DOWN
    }

    public class ConsoleVar
    {
        public static SpriteBatch batch;
        public static SpriteFont font;
        public Vector2 Delta = new Vector2(0, -1);

        public virtual void Draw(Vector2 Orign)
        { }
    };

    public class ConstantVar : ConsoleVar
    {
        public string value;
        public Color color = Color.Yellow;

        public ConstantVar(string value)
        {
            this.value = value;
        }
        public override void Draw(Vector2 Orign)
        {
            
            batch.DrawString(font, value, Orign, color);
            
            base.Draw(Orign);
            
        }


    };

    public class GraphVar : ConsoleVar
    {
        public GraphVar(EngineStuff es ,String graphName , Quadrant quadrant , int numAmostragem , float yMax, float Ymin)
        {
            this.quadrant = quadrant;
            this.numAmostragem = numAmostragem;
            this.yMax = yMax;
            this.Ymin = Ymin;
            this.graphName = graphName;

            _es = es;
            roundLineManager = new RoundLineManager();
            roundLineManager.Init(EngineStuff.GraphicsDevice);
            roundLineTechniqueNames = roundLineManager.TechniqueNames;
            batch = new SpriteBatch(EngineStuff.GraphicsDevice);
            font = EngineStuff.InternalContentManager.GetAsset<SpriteFont>("ConsoleFont");
            Create2DProjectionMatrix();

        }

        private String graphName;
        private Quadrant quadrant;
        private int numAmostragem;
        private float yMax;
        private float Ymin;

        RoundLineManager roundLineManager;
        List<RoundLine> debugLine = new List<RoundLine>();
        LinkedList<float> points = new LinkedList<float>();   
        public static GraphicsDevice gd;
        string[] roundLineTechniqueNames;
        private float lineRadius = 0.002f;
        private Matrix projMatrix;
        EngineStuff _es;
        
        public void addPoint(float v)
        {
            if (points.Count > numAmostragem)
            {
                points.RemoveLast();
            }

            v = (v + Ymin) / (Ymin + yMax);
            if (v > 1.5f) v = 1;
            if (v < 0) v = 0;
            points.AddFirst(v);
        }
        private void Create2DProjectionMatrix()
        {
            // Projection matrix ignores Z and just squishes X or Y to balance the upcoming viewport stretch
            float projScaleX;
            float projScaleY;
            float width = EngineStuff.GraphicsDevice.Viewport.Width;
            float height = EngineStuff.GraphicsDevice.Viewport.Height;
            if (width > height)
            {
                // Wide window
                projScaleX = height / width;
                projScaleY = 1.0f;
            }
            else
            {
                // Tall window
                projScaleX = 1.0f;
                projScaleY = width / height;
            }
            projMatrix = Matrix.CreateScale(projScaleX, projScaleY, 1);
            projMatrix.M43 = 0.5f;
        }
        
        public override void Draw(Vector2 Orign)
        {            
            Matrix viewProjMatrix = projMatrix;
            debugLine.Clear();
            float step = 1.0f / numAmostragem;

            switch (quadrant)
            {
                case Quadrant.LEFT_UP:
                    {
                        batch.Begin(SpriteBlendMode.AlphaBlend,SpriteSortMode.Immediate,SaveStateMode.SaveState);
                        batch.DrawString(font, graphName, new Vector2(50,100), Color.Yellow);
                        batch.End();                          

                        float x = 0;
                        Vector2 vec = new Vector2(0);
                        foreach (var item in points)
                        {
                            Vector2 a = new Vector2(x - 1.3f, (item - 0.30f));
                            if (x == 0)
                                vec = a;

                            debugLine.Add(new RoundLine(vec, a));
                            vec = a;
                            x += step;
                        }
                    }
                    break;
                case Quadrant.LEFT_DOWN:
                    {
                        batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                        batch.DrawString(font, graphName, new Vector2(50, 370), Color.Yellow);
                        batch.End(); 

                        float x = 0;
                        Vector2 vec = new Vector2(0);
                        foreach (var item in points)
                        {
                            Vector2 a = new Vector2(x - 1.3f, (item - 1.50f));
                            if (x == 0)
                                vec = a;

                            debugLine.Add(new RoundLine(vec, a));
                            vec = a;
                            x += step;
                        }
                    }
                    break;
                case Quadrant.RIGHT_UP:
                    {
                        batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                        batch.DrawString(font, graphName, new Vector2(550, 100), Color.Yellow);
                        batch.End(); 

                        float x = 0;
                        Vector2 vec = new Vector2(0);
                        foreach (var item in points)
                        {
                            Vector2 a = new Vector2(x + 0.3f , (item - 0.30f));
                            if (x == 0)
                                vec = a;

                            debugLine.Add(new RoundLine(vec, a));
                            vec = a;
                            x += step;
                        }
                    }
                    break;
                case Quadrant.RIGHT_DOWN:
                    {

                        batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                        batch.DrawString(font, graphName, new Vector2(550, 370), Color.Yellow);
                        batch.End(); 

                        float x = 0;
                        Vector2 vec = new Vector2(0);
                        foreach (var item in points)
                        {
                            Vector2 a = new Vector2(x + 0.3f, (item - 1.50f));
                            if (x == 0)
                                vec = a;

                            debugLine.Add(new RoundLine(vec, a));
                            vec = a;
                            x += step;
                        }
                    }
                    break;
                default:
                    break;
            }          
            string curTechniqueName = roundLineTechniqueNames[0];
            float time = (float)_es.Game.TargetElapsedTime.TotalSeconds;

            batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
            roundLineManager.Draw(debugLine, lineRadius, Color.Red, viewProjMatrix, time, curTechniqueName);
            batch.End();

            //Vector2 P0 = initpos + new Vector2(0, points.[initpoint]);
            //int max;
            //if (points.Count > pointstoDraw)
            //{
            //    max = pointstoDraw;
            //    initpoint = points.Count - pointstoDraw;
            //}
            //else
            //{
            //    max = points.Count;
            //}
            //for (int i = initpoint ; i < initpoint + max; i++)
            //{
            //    debugLine.Add(new RoundLine(P0, new Vector2(dd, points[i] / factor)));
            //    P0 = new Vector2(dd, points[i] / factor);
            //    dd += numberDelta;
            //}
            //batch.Begin();
            //batch.DrawString(font, points.Last().ToString(), Orign, Color.Red);
            //batch.End();
            
            base.Draw(Orign);           
        }

    };
}
